<script lang="ts" setup>
import * as L from 'leaflet';
import { ref, onMounted, onUnmounted } from 'vue';
import "leaflet/dist/leaflet.css";
import 'leaflet.chinatmsproviders';
import 'proj4leaflet';
import 'proj4';
import List from './List.vue';
import * as signalR from '@microsoft/signalr';
import { ElNotification } from 'element-plus';
import EventBus from './EventBus';

const MapKey = "c821b8bede8a0e999e88ac75e39a7898";
let map: L.Map;
const sessionId = ref<string | null>(null);
const sessionId2 = ref<string | null>(null);
const elementNames = ref<{ id: string, name: string }[]>([]);
const ruleDataTemp = ref<{}[]>([]);
const polygons = ref<{ [key: string]: L.Polygon }>({});
const markers = ref<{ [key: string]: L.Marker }>({});
const assignedCounts = ref<{ [key: string]: number }>({});

// 创建音频对象
const alarmSound = new Audio('/2570.mp3');
alarmSound.loop = true; // 设置音频循环播放

const staffIcon = L.icon({
  iconUrl: '/staff.png',
  iconSize: [32, 32],
});

let connection: signalR.HubConnection;

async function fetchRegionPoints(regionId: string) {
  try {
    const response = await fetch(`http://47.100.168.221:9999/gps-web/api/get_region_points.jsp?sessionId=${sessionId.value}&id=${regionId}`);
    const data = await response.json();
    if (data && data.entity && data.entity.points) {
      return data.entity.points.split(";").map((point: string) => {
        const [lng, lat] = point.split(",");
        return [parseFloat(lat), parseFloat(lng)] as [number, number];
      });
    }
    return null;
  } catch (error) {
    console.error("Error fetching region points:", error);
    return null;
  }
}

async function fetchData() {
  const login1 = await fetch(`http://47.100.168.221:9999/gps-web/api/login.jsp?password=c65c636e668a7872e393058856be20f5&userId=SHJC_PDGJ&loginType=user`);
  const loginData1 = await login1.json();
  sessionId.value = loginData1.sessionId;

  const login2 = await fetch(`http://47.100.168.221:9999/gps-web/api/login.jsp?password=e10adc3949ba59abbe56e057f20f883e&userId=user_shjt&loginType=user`);
  const loginData2 = await login2.json();
  sessionId2.value = loginData2.sessionId;

  const regionsResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_regions.jsp?sessionId=${sessionId.value}&type=1`);
  const regionsData = await regionsResponse.json();
  if (regionsData && regionsData.data) {
    elementNames.value = regionsData.data.map((element: any) => ({
      id: element.id,
      name: element.name
    }));

    const ruleResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_rules.jsp?sessionId=${sessionId2.value}&ruleType=3`);
    const ruleData = await ruleResponse.json();
    if (ruleData && ruleData.data) {
      for (const item of ruleData.data) {
        const ruleListResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_rule_assign.jsp?sessionId=${sessionId2.value}&type=rule&resId=${item.id}`);
        const ruleListData = await ruleListResponse.json();
        if (ruleListData.list && ruleListData.list.length > 5) {
          ruleDataTemp.value.push(item.regionId);
        }
        assignedCounts.value[item.regionId] = ruleListData.list.length;
      }
    }
  } else {
    console.error("Error fetching or processing regions data.");
  }
}

function initializeMap() {
  const imgm = L.tileLayer.chinaProvider('TianDiTu.Satellite.Map', {
    maxZoom: 22,
    minZoom: 12,
    key: MapKey
  });
  const imga = L.tileLayer.chinaProvider('TianDiTu.Satellite.Annotion', {
    maxZoom: 22,
    minZoom: 12,
    key: MapKey
  });

  const image = L.layerGroup([imgm, imga]);
  const baseLayers = {
    "影像": image,
  };
  const overlayLayers = {
    "影像": image,
  };

  map = L.map("map", {
    center: [31.144339395192617, 121.80826876009174],
    zoom: 14,
    minZoom: 12,
    layers: [image],
    zoomControl: false,
  });

  L.control.layers(baseLayers, overlayLayers).addTo(map);
  let attribution = map.attributionControl;
  attribution.setPrefix('<span><img height=10 src="https://www.ollama.com/public/ollama.png"> 上海疆通科技</span>');
  L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '数据引自 <a href="https://www.tianditu.gov.cn">&copy; 天地图</a>'
  }).addTo(map);

  elementNames.value.forEach(async (element: any) => {
    const coordinates = await fetchRegionPoints(element.id);
    if (coordinates) {
      const polygon = L.polygon([coordinates], {
        color: ruleDataTemp.value.includes(element.id) ? 'green' : 'blue',
        fillColor: ruleDataTemp.value.includes(element.id) ? 'green' : 'none',
        fillOpacity: ruleDataTemp.value.includes(element.id) ? 0.5 : 0.15
      }).addTo(map);
      polygons.value[element.id] = polygon;
      polygon.bindPopup(element.name);
      polygon.on('click', function () {
        polygon.bringToFront();
      });
    }
  });
}

await fetchData();

let updateTimer: NodeJS.Timeout;

onMounted(async () => {
  initializeMap();

  updateTimer = setInterval(async () => {
    await fetchData();
  }, 2000);

  connection = new signalR.HubConnectionBuilder()
    .withUrl("http://101.126.16.147:5458/location")
    .withAutomaticReconnect()
    .build();

  connection.start()
    .then(() => console.log("SignalR connected."))
    .catch((err: any) => console.error("Error connecting to SignalR:", err));

  connection.on("OrientationMessage", (positionData: any) => {
    positionData = JSON.parse(positionData);
    console.log("Received positionData:", positionData);

    const { carId, lat, lng, carName } = positionData;

    if (markers.value[carId]) {
      const marker = markers.value[carId];
      marker.setLatLng([lat, lng]);
    } else {
      const marker = L.marker([lat, lng], {
        icon: staffIcon
      }).addTo(map).bindPopup(carName);

      marker.setZIndexOffset(99);

      markers.value[carId] = marker;
    }
  });

  connection.on("AlarmMessage", async (alarmData: any) => {
    const alarmData1 = JSON.parse(alarmData);
    console.log("%c Line:210 🍧 alarmData", "color:#e41a6a", alarmData);

    const { alarmName, carId, carName, alarmTime, typeId, addr } = alarmData1;

    if (typeId === 'r4' && addr?.includes("浦东")) {
      ElNotification({
        title: alarmName,
        message: `${carName}<br>${alarmTime}`,
        type: 'warning',
        position: 'top-right',
        duration: 60000,
        offset: 56,
        dangerouslyUseHTMLString: true,
      });

      // 播放报警铃声
      alarmSound.play();
    }

    async function fetchAlarmCondition() {
      const response = await fetch(`http://47.100.168.221:9999/gps-web/api/get_alarm_condition.jsp?sessionId=${sessionId.value}`);
      const alarmConditionData = await response.json();
      const r4NotSolvedNum = alarmConditionData.map?.r4?.notSolvedNum ?? 0;

      // 发送 notSolvedNum 到 Header.vue
      EventBus.emit('updateAlarmCount', r4NotSolvedNum);

      // 根据 r4NotSolvedNum 控制音频播放
      if (r4NotSolvedNum === 0) {
        alarmSound.pause();
        alarmSound.currentTime = 0;
      }
    }

    await fetchAlarmCondition();

    if (typeId === 'p1' || typeId === 'p2') {
      const marker = markers.value[carId];
      if (marker) {
        marker.setPopupContent(`${carName}<br>低电量警告<br>${alarmTime}`);
        marker.openPopup();
      }
    }
  });

  connection.on("OnlineMessage", (onlineData: any) => {
    onlineData = JSON.parse(onlineData);
    console.log("Received onlineData:", onlineData);

    const { carId, isOnline } = onlineData;

    if(isOnline === 'false') {
      if(markers.value[carId]) {
        map.removeLayer(markers.value[carId]);
        delete markers.value[carId];
      }
    }
  });
});

onUnmounted(() => {
  connection && connection.stop()
  map && map.remove();
  clearInterval(updateTimer);
});

const toggleRegion = (regionId: string, isSelected: boolean) => {
  if (polygons.value[regionId]) {
    if (isSelected) {
      polygons.value[regionId].addTo(map);
    } else {
      map.removeLayer(polygons.value[regionId]);
    }
  }
};
</script>

<template>
  <div class="flex h-screen">
    <List :elementNames="elementNames" :ruleData="ruleDataTemp" :assignedCounts="assignedCounts" @toggleRegion="toggleRegion" />
    <div id="map" class="flex-1 h-full"></div>
  </div>
</template>

<style>
.leaflet-top.leaflet-right {
  display: none;
}
</style>
